package orderProcessingProcess.client.junit;

import orderProcessingProcess.model.Address;
import orderProcessingProcess.model.Customer;
import orderProcessingProcess.model.Payment_Preference;

import org.apache.cxf.jaxrs.client.WebClient;
import javax.ws.rs.core.Response;

import junit.framework.Assert;
import org.junit.Test;

public class TestCustomerManagementService {

	private static String customerServiceAddress = "http://localhost:8085/customers/";
	
	@Test
	public void testGetCustomer() {
		
		// Test get customer 00001 with xml
		WebClient wc = WebClient.create(customerServiceAddress );
		Customer c = wc.path("00001").accept("application/xml").get(Customer.class);
		Assert.assertNotNull(c);
		Assert.assertEquals("00001", c.getId());

		// Test get customer 00002 with json
		wc = WebClient.create(customerServiceAddress );
		c = wc.path("00002").accept("application/json").get(Customer.class);
		Assert.assertNotNull(c);
		Assert.assertEquals("00002", c.getId());
		
		// Test get customer 00003 with both types
		wc = WebClient.create(customerServiceAddress );
		c = wc.path("00003").accept("application/xml, application/json").get(Customer.class);
		Assert.assertNotNull(c);
		Assert.assertEquals("00003", c.getId());

		// Test get non-existent customer
		wc = WebClient.create(customerServiceAddress );
		Response r = wc.path("xyz").accept("application/json").get();
		Assert.assertEquals( Response.Status.NOT_FOUND.getStatusCode(), r.getStatus());
	}
	
	@Test
	public void testAddCustomer() {
		Address a9 = new Address();
		a9.setId("009");
		a9.setStreet("9th Street");
		a9.setCity("San Francisco");
		a9.setHouse(9);
		a9.setDoor(9);
		a9.setZip_code("90000");

		Customer c9 = new Customer();
		c9.setId("00009");
		c9.setName("Joe Niner");
		c9.setAddress(a9);
		c9.setPaymentPreference(Payment_Preference.Credit_Card);

		WebClient wc = WebClient.create(customerServiceAddress );
		Response r = wc.path("/").type("application/xml").post(c9);
		Assert.assertEquals( Response.Status.OK.getStatusCode(), r.getStatus() );

		wc = WebClient.create(customerServiceAddress );
		Customer c = wc.path("00009").type("application/json").get(Customer.class);
		Assert.assertNotNull(c);
		Assert.assertEquals( "00009", c.getId());

		// delete added customer
		wc = WebClient.create(customerServiceAddress );
		wc.path("00009").delete();
	}
	
	@Test
	public void testUpdateCustomer() {
		// get customer 00004
		WebClient wc = WebClient.create(customerServiceAddress );
		Customer c_old = wc.path("00004").accept("application/json").get(Customer.class);
		
		// change name and payment Preference
		Customer c_new = c_old;
		c_new.setName("Mary Bar-None");
		c_new.setPaymentPreference(Payment_Preference.Bank_Transfer);
		
		// update customer
		wc = WebClient.create(customerServiceAddress );
		Response r = wc.path("00004").type("application/json").put(c_new);
		Assert.assertEquals( Response.Status.OK.getStatusCode(), r.getStatus() );
		
		// get customer data and verify changes

		// again, a new WebClient object for a new type
		wc = WebClient.create(customerServiceAddress );
		c_new = wc.path("00004").type("application/xml").get(Customer.class);
		Assert.assertNotNull(c_new);
		Assert.assertEquals( "00004", c_new.getId());
		Assert.assertEquals( "Mary Bar-None", c_new.getName() );
		Assert.assertTrue( c_new.getPaymentPreference() == Payment_Preference.Bank_Transfer );
        
		// try to update with conflicting path and id in customer
		wc = WebClient.create(customerServiceAddress );
		r = wc.path("00005").type("application/xml").put(c_new);
		Assert.assertEquals( Response.Status.NOT_MODIFIED.getStatusCode(), r.getStatus());

		// try to update customer that does not exist
		c_new.setId("abc");
		wc = WebClient.create(customerServiceAddress );
		r = wc.path("abc").type("application/xml").put(c_new);
		Assert.assertEquals( Response.Status.NOT_FOUND.getStatusCode(), r.getStatus());

		// restore old customer data
		wc = WebClient.create(customerServiceAddress );
		wc.path("00004").type("application/json").put(c_new);
	}
	
	@Test
	public void testDeleteCustomer() {

		WebClient wc = WebClient.create(customerServiceAddress );

		// remember this customer so that we can restore him after the test
		Customer c3 = wc.path("00003").type("application/json").get(Customer.class);

		// delete customer 00003
		wc = WebClient.create(customerServiceAddress );
		Response r = wc.path("00003").delete();
		Assert.assertEquals( Response.Status.OK.getStatusCode(), r.getStatus() );
        
		// check that customer 00003 cannot be found 
		wc = WebClient.create(customerServiceAddress );
		r = wc.path("00003").type("application/json").get();
		Assert.assertEquals( Response.Status.NOT_FOUND.getStatusCode(), r.getStatus() );
        
		// try do delete non-existent customer
		wc = WebClient.create(customerServiceAddress );
		r = wc.path("/zyx").delete();
		Assert.assertEquals( Response.Status.NOT_FOUND.getStatusCode(), r.getStatus() );

		// restore the customer
		wc = WebClient.create(customerServiceAddress );
		wc.path("/").type("application/json").post(c3);
	}
	
}
